package br.uniceub.fsw.arquitetura.interfaces.facade;

import br.uniceub.fsw.util.ConfirmacaoVO;
import br.uniceub.fsw.util.ErroVO;
import br.uniceub.fsw.util.Html;
import br.uniceub.fsw.util.InformacaoVO;
import br.uniceub.fsw.util.Validacao;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.servlet.http.HttpServletRequest;


/**
 * 
 * <i>Classe-mae</i> para <b>toda</b> FACADE criada. <br/>
 * <b>Exemplo: public class MeuFACADE extends BaseFACADE {<br/>
 * 
 * atributos<br/>
 * .<br/>
 * .<br/>
 * .<br/>
 * 
 * me'todos()<br/>
 * .<br/>
 * .<br/>
 * .<br/>
 * 
 * }</b>
 * <br/>
 * <br/>
 * <p align='justify'>
 * Classe responsavel por gerar o HTML dinamico
 * na camada VIEW, tratar dados (lado servidor) de acordo com regras
 * pre-estabelecidas (como tamanho de campos, p.ex.),
 * notificar ao usuario sobre acoes bem sucedidas,
 * erros no preenchimento dos campos e informacoes.
 * Ale'm de poder, tambe'm, facilitar a inclusao dos arquivos
 * auxiliares para interface: CSS (estilos) e JS 
 * (validacao e tratamento de entrada de dados do lado cliente).
 * </p>
 *  
 * @author sergiofernandomuniz
 * @version 1.0
 * @since marco/2009
 * @see Veja as classes 'InputHtml', 'CorfirmacaoVO', 'InformacaoVO', 
 * 'ErroVO', 'MontarCssJs', 'TratamentoErros', 'Validacao'.
 */
public class BaseFacade{
    

    private static ArrayList<ErroVO> listaMensagensErro;
    private static String dsConfirmacao;
    private static String dsInformacao;
    private static ArrayList<Object> listaMensagensAoUsuario;
    
    public BaseFacade(){
        
        /*listaMensagensAoUsuario = new ArrayList<Object>();
        listaMensagensErro = new ArrayList<ErroVO>();
        dsConfirmacao = new String();
        dsInformacao = new String();*/
        
    }
    
    @SuppressWarnings("static-access")
    public String verificaFuncionalidade(HttpServletRequest request) throws Exception{
        
        String funcionalidade = this.recuperaAtributoTela("funcionalidade");
        
        if(funcionalidade == null){
            
            return "";
            
        }
        
        if(funcionalidade.equals("validar")){
            
            String nome = this.recuperaAtributoTela("noAluno");

            if(Validacao.validaNome(nome) != null){

                this.adicionaErro(Validacao.validaNome(nome).getDsErro());

            }else{

                return new ConfirmacaoVO("Dado aceito!").getDsConfirmacao();

            }
            
            return "";
            
        }
        
        return "";
        
    }
    
    public static StringBuffer retornaMensagemErroTeste(){
        
        ErroVO erro = new ErroVO("Você não tem permissão para " +
                "acessar essa página. Contate o administrador do sistema");
        
        return ErroVO.montaMensagemErro(erro.getDsErro());
        
    }
    
    public static StringBuffer retornaListaMensagensErroTeste(){
        
        listaMensagensErro = new ArrayList<ErroVO>();
        
        ErroVO erro = new ErroVO("Sua senha está expirada.");
        listaMensagensErro.add(erro);
        
        erro = new ErroVO("O CPF preenchido é inválido.");
        listaMensagensErro.add(erro);
        
        erro = new ErroVO("O limite para o campo NOME foi ultrapassado, o que " +
                "evita o armazenamento da informação.");
        listaMensagensErro.add(erro);
        
        return ErroVO.montaMensagemErros(listaMensagensErro);
        
    }
    
    public static StringBuffer retornaMensagemInfoTeste(){
        
        dsInformacao = new String("Sua senha expira em 5 dias.");
        
        return InformacaoVO.montaMensagemInformacao(dsInformacao);
        
    }
    
    public static StringBuffer retornaMensagemConfirmacaoTeste(){
        
        dsConfirmacao = new String("Os dados foram alterados com sucesso.");
        
        return ConfirmacaoVO.montaMensagemConfirmacao(dsConfirmacao);
        
    }
    
    public static StringBuffer retornaTodasMensagensAoUsuario(){
        
        StringBuffer sb;
        
        listaMensagensErro = new ArrayList<ErroVO>();
        
        /*
        listaMensagensErro = new ArrayList<ErroVO>();
        ErroVO vo = new ErroVO("Exemplo de erro");
        listaMensagensErro.add(vo);
        
        sb.append(ErroVO.montaMensagemErros(listaMensagensErro));
        sb.append(InformacaoVO.montaMensagemInformacao("Exemplo de informacao"));
        sb.append(ConfirmacaoVO.montaMensagemConfirmacao("Exemplo de confirmacao"));
        
        return sb;*/
        
        if(listaMensagensErro.isEmpty()){
            
            sb = new StringBuffer();
            return sb.append("");
            
        }
        
        else{
            
            sb = new StringBuffer();
            
            for(int i = 0; i < listaMensagensErro.size(); i++){
                
                sb.append(listaMensagensErro.get(i).getDsErro());
                
            }
            
            return sb;
            
        }
        
    }

    public static StringBuffer retornaMensagensAoUsuario(
            ArrayList<ErroVO> listaMensagensErro){

        StringBuffer sb = new StringBuffer();

        sb.append(ErroVO.montaMensagemErros(listaMensagensErro));

        return sb;

    }

    public static StringBuffer retornaMensagensAoUsuario(InformacaoVO informacao){

        StringBuffer sb = new StringBuffer();

        sb.append(InformacaoVO.montaMensagemInformacao(informacao.getDsInformacao()));

        return sb;

    }

    public static StringBuffer retornaMensagensAoUsuario(ConfirmacaoVO confirmacao){

        StringBuffer sb = new StringBuffer();

        sb.append(ConfirmacaoVO.montaMensagemConfirmacao(confirmacao.getDsConfirmacao()));

        return sb;

    }

    public static StringBuffer retornaMensagensAoUsuario(ConfirmacaoVO confirmacao,
            InformacaoVO informacao){

        StringBuffer sb = new StringBuffer();

        sb.append(ConfirmacaoVO.montaMensagemConfirmacao(confirmacao));
        sb.append(InformacaoVO.montaMensagemInformacao(informacao));

        return sb;

    }

    public static StringBuffer retornaMensagensAoUsuario(String dsConfirmacao){

        StringBuffer sb = new StringBuffer();

        sb.append(ConfirmacaoVO.montaMensagemConfirmacao(dsConfirmacao));

        return sb;

    }

    public static StringBuffer retornaMensagensAoUsuario(String dsConfirmacao,
            String dsInformacao){

        StringBuffer sb = new StringBuffer();

        sb.append(ConfirmacaoVO.montaMensagemConfirmacao(dsConfirmacao));
        sb.append(InformacaoVO.montaMensagemInformacao(dsInformacao));

        return sb;

    }

    /**
     * @param Mensagem de informacao.<br/>
     * Exemplo:     retornaMensagemAlteracaoFormulario("Seus dados foram alterados.");
     */
    public StringBuffer retornaMensagemAlteracaoFormulario(String mensagemConfirmacao){
        
        if(!BaseFacade.verificaSeListaEstaVazia(listaMensagensErro)){
                
            ConfirmacaoVO vo = new ConfirmacaoVO();
            
            return vo.montaMensagemConfirmacao(mensagemConfirmacao);
            
        }
        
        return null;
        
    }
    
     /**
     * Exemplo:     retornaMensagemPadraoAlteracao();<br/>
     * Saida:       Os dados foram alterados com sucesso.
     */
    public StringBuffer retornaMensagemPadraoAlteracao(){
        
        if(!BaseFacade.verificaSeListaEstaVazia(listaMensagensErro)){
                
            ConfirmacaoVO vo = new ConfirmacaoVO();
            
            return vo.montaMensagemConfirmacaoPadrao();
            
        }
        
        return null;
        
    }
    
    
    /**
     * 
     * @param Descricao do erro. <br/>
     * Exemplos:    O campo nome excedeu o limite de caracteres.<br/>
     *              A opcao selecionada eh invalida.<br/>
     * Aplicação do método: adicionaErro("O CPF informado e' inva'lido."). <br/>
     */
    public void adicionaErro(String dsErro){
        
        ErroVO erro = new ErroVO();

        erro.setDsErro(dsErro);

        if (!ErroVO.validaErro(dsErro, listaMensagensErro)) {
            
            listaMensagensErro.add(erro);

        }
            
    }

    /*
    protected void adicionaConfirmacaoNaListaConfirmacao(String dsConfirmacao){
        
        ConfirmacaoVO confirmacao = new ConfirmacaoVO();

        confirmacao.setDsConfirmacao(dsConfirmacao);

        if (!ConfirmacaoVO.validaConfirmacao(dsConfirmacao, listaMensagensConfirmacao)){
            
            listaMensagensConfirmacao.add(confirmacao);

        }
            
    }
    */
    
    /*protected void adicionaInformacaoNaListaInformacao(String dsInformacao){
        
        InformacaoVO informacao = new InformacaoVO();

        informacao.setDsInformacao(dsInformacao);

        if (!InformacaoVO.validaConfirmacao(dsInformacao, listaMensagensInformacao)){

            listaMensagensInformacao.add(informacao);

        }
            
    }*/
        
    /**
     * 
     * @param Descricao do erro. <br/>
     * Os dois métodos tem o mesmo nome. 
     * Note a chamada estática ErroVO.verificaSeErroEstaNuloOuVazio(dsErro)
     * 
     */
    protected boolean verificaSeErroEstaNuloOuVazio(String dsErro){
        
        if(!ErroVO.verificaSeErroEstaNuloOuVazio(dsErro)){
            
            ErroVO erro = new ErroVO();
            
            erro.setDsErro("O formulário contém erros de preenchimento.");

            return true;
            
        }
        
        return false;
        
    }

    public StringBuffer retornaErroFormulario(ArrayList listaErrosExecucao){
        
        return ErroVO.montaMensagemErros(listaErrosExecucao);
        
    }
    
    public StringBuffer retornaInformacoesFormulario(String dsInformacao){
        
        return InformacaoVO.montaMensagemInformacao(dsInformacao);
        
    }
    
    public StringBuffer retornaConfirmacoesFormulario(String dsConfirmacao){
        
        return ConfirmacaoVO.montaMensagemConfirmacao(dsConfirmacao);
        
    }
    
    /**
     * <p>
     * Saida:       <i>CSS</i> e <i>JS</i> (dependencias) inseridos automaticamente no 
     * JSP no qual o método for chamado. A chamada pode ser atrave's de <i>scriplet</i>
     * ou por meio de substituicao de <i>tags</i> personalizadas.</p><br/>
     * Exemplo:<br/>
     * <b><i>Scriptlet:</i></b>
     * <i>apelidoDoBackingBean.montarCabecalhoJSP()</i><br/>
     * <b><i>Substituicao:</i></b>
     * {minhaTagASerSubstituida} -> A substituicao é realizada pelo me'todo
     * pu'blico presente nessa classe: 
     * <i>substituiTagPersonalizadaPorConteudoDinamico(String nomeTag)</i>
     * 
     */
    public static StringBuffer montarCabecalhoJSP(){

        StringBuffer sb = Html.montarCabecalhoJSP();
        return sb;

    }
    
    public static String montarCabecalhoJSPEmFormaDeString(){

        StringBuffer sb = Html.montarCabecalhoJSP();
        return sb.toString();

    }

    public static void validaCamposFormulario(Object vo) throws Exception{
        
        ArrayList<String> listaAtributosVO = BaseFacade.recuperaAtributosVO(vo);
        
        for(int i = 0; i < listaAtributosVO.size(); i++){
            
            String campoFormulario = listaAtributosVO.get(i);
            
            distribuiValidacaoCamposFormulario(campoFormulario, BaseFacade.recuperaAtributoTela(campoFormulario));
            
            System.out.println("\nCampo total" + campoFormulario + "\n");
            
            }
            
    }
    
    public static void distribuiValidacaoCamposFormulario (String campoFormulario,
            String valorCampoFormulario){
        
        String campo = new String();
        
        campo = Character.toString(campoFormulario.charAt(0));
        campo += Character.toString(campoFormulario.charAt(1));
        
        System.out.println("Distribuicao:" +campo);
        
        if(campo.equals("dt")){
            
            Validacao.validaData(valorCampoFormulario);
            
        }
        
        if(campo.equals("no")){
            
            Validacao.validaNome(valorCampoFormulario);
            
        }
        
    }
    
    public static ArrayList<String> recuperaAtributosTela(
            ArrayList<String> listaAtributosVO){

        ArrayList<String> listaAtributosTela = new ArrayList<String>();

       for(int i = 0; i < listaAtributosVO.size(); i++){

           HttpServletRequest req = null;
           
           String atributoTela = (String)req.getAttribute(listaAtributosVO.get(i));
           
           System.out.println(atributoTela);
           
           listaAtributosTela.add(atributoTela);
           
        }


        return listaAtributosTela;

    }
    
    public static String recuperaAtributoTela(String nomeCampo){

           HttpServletRequest req = null;
           
           String valorAtributoTela = req.getParameter(nomeCampo);
           
           if(!Validacao.validaSeValorCampoEstaNuloOuVazio(valorAtributoTela)){
               
                return valorAtributoTela;
               
           }
           
           return null;

    }

    public static ArrayList recuperaAtributosVO(Object vo) throws InstantiationException, IllegalAccessException{

        ArrayList<String> listaAtributosVO = new ArrayList<String>();

        Class objeto = vo.getClass();

        try {

               objeto.newInstance();

        } catch (InstantiationException ex) {

              ex.printStackTrace();

        }

        Method metodos[] = vo.getClass().getDeclaredMethods();

        for (int i = 0; i < metodos.length; i++) {

            if (metodos[i].getName().startsWith("get")) {
                
                StringTokenizer stk = new StringTokenizer(metodos[i].getName().toString(), ".");
                String aux;
                char c;
                
                aux = stk.nextToken().substring(3);
                c = aux.charAt(0);
                aux = aux.replace(String.valueOf(c).toString(), String.valueOf(c).toLowerCase());
                
                listaAtributosVO.add(aux);
                
                System.out.print(aux);

            }
        }

        return listaAtributosVO;

    }
    
    public static boolean verificaSeListaEstaVazia(ArrayList<?> 
            listaMensagensAoUsuario){
        
        if(listaMensagensAoUsuario.isEmpty()){
            
            return true;
            
        }
        
        else{
            
            return false;
            
        }
        
    }
    
    
    /*
    public boolean seListaErrosExecucaoVazia(ArrayList listaErrosExecucao){
        
        if(listaErrosExecucao.isEmpty()){
            
            return true;
            
        }else{
            
            return false;
            
        }
        
        
    }

    */

    public static ArrayList<Object> getListaMensagensAoUsuario() {
        return listaMensagensAoUsuario;
    }

    public static void setListaMensagensAoUsuario(ArrayList<Object> listaMensagensAoUsuario) {
        BaseFacade.listaMensagensAoUsuario = listaMensagensAoUsuario;
    }

    public static ArrayList<ErroVO> getListaMensagensErro() {
        return listaMensagensErro;
    }

    public static void setListaMensagensErro(ArrayList<ErroVO> listaMensagensErro) {
        BaseFacade.listaMensagensErro = listaMensagensErro;
    }

    public static String getDsConfirmacao() {
        return dsConfirmacao;
    }

    public static void setDsConfirmacao(String dsConfirmacao) {
        BaseFacade.dsConfirmacao = dsConfirmacao;
    }

    public static String getDsInformacao() {
        return dsInformacao;
    }

    public static void setDsInformacao(String dsInformacao) {
        BaseFacade.dsInformacao = dsInformacao;
    }


    
}